package com.payment.notify.core;

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

import org.payment.core.utils.httpclient.SimpleHttpParam;
import org.payment.core.utils.httpclient.SimpleHttpResult;
import org.payment.core.utils.httpclient.SimpleHttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springside.modules.utils.mapper.JsonMapper;

import com.payment.common.exceptions.ServiceException;
import com.payment.notify.PaymentAppNotifyApplication;
import com.payment.notify.domain.TblTradeNotifyRecord;
import com.payment.notify.dto.NotifyParam;
import com.payment.notify.enums.NotifyStatusEnum;

/**
 * 类名：NotifyTask.java<br>
 * 描述：执行通知的类，以后有业务时添加业务代码即可<br>
 * 创建者：XINJF<br>
 * 创建日期：2018年4月20日下午1:57:56<br>
 * 版本：1.0<br>
 * 修改者：<br>
 * 修改日期：<br>
 */

public class NotifyTask implements Runnable, Delayed {

	private Logger logger = LoggerFactory.getLogger(NotifyTask.class);

	private long executeTime;

	private TblTradeNotifyRecord notifyRecord;

	private NotifyQueue notifyQueue;

	private NotifyParam notifyParam;

	private NotifyPersist notifyPersist = PaymentAppNotifyApplication.notifyPersist;

	public NotifyTask() {
	}

	public NotifyTask(TblTradeNotifyRecord notifyRecord, NotifyQueue notifyQueue, NotifyParam notifyParam) {
		super();
		this.notifyRecord = notifyRecord;
		this.notifyQueue = notifyQueue;
		this.notifyParam = notifyParam;
		this.executeTime = this.getExecuteTime(notifyRecord);
	}

	private long getExecuteTime(TblTradeNotifyRecord record) {
		long lastTime = record.getLastNotifyTime().getTime();
		Integer nextNotifyTime = notifyParam.getNotifyParams().get(record.getNotifyTimes());
		return (nextNotifyTime == null ? 0 : nextNotifyTime * 1000) + lastTime;
	}

	public int compareTo(Delayed o) {
		NotifyTask task = (NotifyTask) o;
		System.out.println("task.executeTime==" + task.executeTime);
		return executeTime > task.executeTime ? 1 : (executeTime < task.executeTime ? -1 : 0);
	}

	@Override
	public long getDelay(TimeUnit unit) {
		return unit.convert(executeTime - System.currentTimeMillis(), unit.SECONDS);
	}

	@Override
	public void run() {
		// 得到当前通知对象的通知次数
		Integer notifyTimes = notifyRecord.getNotifyTimes();
		System.out.println("notifyTimes==" + notifyTimes);
		// 去通知
		try {
			logger.info("Notify Url " + notifyRecord.getUrl() + " ;notify id:" + notifyRecord.getId() + ";notify times:"
					+ notifyRecord.getNotifyTimes());

			SimpleHttpParam param = new SimpleHttpParam(notifyRecord.getUrl());
			SimpleHttpResult result = SimpleHttpUtils.httpRequest(param);

			notifyRecord.setNotifyTimes(notifyTimes + 1);
			String successValue = notifyParam.getSuccessValue();
			System.out.println("successValue==" + successValue);

			String responseMsg = "";
			Integer responseStatus = result.getStatusCode();

			// 得到返回状态，如果是200，也就是通知成功
			if (result != null
					&& (responseStatus == 200 || responseStatus == 201 || responseStatus == 202 || responseStatus == 203
							|| responseStatus == 204 || responseStatus == 205 || responseStatus == 206)) {
				responseMsg = result.getContent().trim();
				responseMsg = responseMsg.length() >= 600 ? responseMsg.substring(0, 600) : responseMsg;
				logger.info("内容： " + notifyRecord.getMerchantOrderNo() + " HTTP_STATUS：" + responseStatus + "请求返回信息："
						+ responseMsg);
				// 通知成功
				if (responseMsg.trim().equals(successValue)) {
					notifyPersist.updateNotifyRord(notifyRecord.getId(), notifyRecord.getNotifyTimes(),
							NotifyStatusEnum.SUCCESS.getValue());
				} else {
					notifyQueue.addElementToList(notifyRecord);
					notifyPersist.updateNotifyRord(notifyRecord.getId(), notifyRecord.getNotifyTimes(),
							NotifyStatusEnum.HTTP_REQUEST_SUCCESS.getValue());

				}
				logger.info("Update NotifyRecord:" + JsonMapper.INSTANCE.toJson(notifyRecord) + ";responseMsg:"
						+ responseMsg);
			} else {
				notifyQueue.addElementToList(notifyRecord);
				// 再次放到通知列表中，由添加程序判断是否已经通知完毕或者通知失败
				notifyPersist.updateNotifyRord(notifyRecord.getId(), notifyRecord.getNotifyTimes(),
						NotifyStatusEnum.HTTP_REQUEST_FALIED.getValue());
			}

			// 写通知日志表
			notifyPersist.saveNotifyRecordLogs(notifyRecord.getId(), notifyRecord.getMerchantNo(),
					notifyRecord.getMerchantOrderNo(), notifyRecord.getUrl(), responseMsg, responseStatus,notifyRecord.getContent());
			logger.info("Insert NotifyRecordLog, content:" + notifyRecord.getMerchantOrderNo());
		} catch (ServiceException e) {
			logger.error("NotifyTask", e);
		} catch (Exception e) {
			logger.error("NotifyTask", e);
			notifyQueue.addElementToList(notifyRecord);

			notifyPersist.updateNotifyRord(notifyRecord.getId(), notifyRecord.getNotifyTimes(),
					NotifyStatusEnum.HTTP_REQUEST_FALIED.getValue());
			notifyPersist.saveNotifyRecordLogs(notifyRecord.getId(), notifyRecord.getMerchantNo(),
					notifyRecord.getMerchantOrderNo(), notifyRecord.getUrl(), "", 0,notifyRecord.getContent());
		}

	}
}
